Виджеты. Цветовая тема приложения

➡️ Скачать презентацию. Flutter Цветовая Тема
➡️ Ссылка на репозиторий с кодом этого урока

Работа с ThemeData

Хорошей практикой является создание отдельного файла/класса в котырый выносится вся работа со стилями приложения (цвет, текст, оформление виджетов и т.п.)

Добавим в проект новый файл app_theme.dart в папке lib

В этом файле напишем класс AppTheme, который будет содержать статический метод lightTheme для возврата объекта ThemeData с настроенной темой для приложения.

Файл app_theme.dart

import 'package:flutter/material.dart';

class AppTheme {
  // Статический метод для получения светлой темы приложения
  static ThemeData lightTheme() {
    // Создаем цветовую схему на основе одного "начального" цвета.
    // Flutter автоматически генерирует различные оттенки и цвета для разных целей (primary, secondary, surface и т.д.).
    final ColorScheme colorScheme = ColorScheme.fromSeed(seedColor: Colors.green);


    return ThemeData(
      colorScheme: colorScheme,
      // Определяем тему для всех виджетов AppBar в приложении.
      appBarTheme: AppBarTheme(
        // Цвет фона AppBar
        backgroundColor: colorScheme.primary,
        // Цвет содержимого на AppBar
        foregroundColor: colorScheme.onPrimary,
        // Выравнивание заголовка по центру
        centerTitle: true,
      ),

      // Определяем тему для всех кнопок
      elevatedButtonTheme: ElevatedButtonThemeData(
        style: ElevatedButton.styleFrom(
          // Цвет фона кнопки
          backgroundColor: colorScheme.primary,
          // Цвет содержимого
          foregroundColor: colorScheme.onPrimary,
          // Внутренние отступы кнопки
          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 0),
          // Скругленные углы
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
        ),
      ),

      // Определяем тему для различных стилей текста
      textTheme: TextTheme(
        displayLarge: TextStyle(fontSize: 57, color: colorScheme.onSurface),
        displayMedium: TextStyle(fontSize: 45, color: colorScheme.onSurface),
        displaySmall: TextStyle(fontSize: 36, color: colorScheme.onSurface),
        headlineLarge: TextStyle(fontSize: 32, color: colorScheme.onSurface),
        headlineMedium: TextStyle(fontSize: 28, color: colorScheme.onSurface),
        headlineSmall: TextStyle(fontSize: 24, color: colorScheme.onSurface),
        titleLarge: TextStyle(fontSize: 22, color: colorScheme.onSurface),
        titleMedium: TextStyle(fontSize: 16, color: colorScheme.onSurface),
        titleSmall: TextStyle(fontSize: 14, color: colorScheme.onSurface),
        bodyLarge: TextStyle(fontSize: 16, color: colorScheme.onSurface),
        bodyMedium: TextStyle(fontSize: 14, color: colorScheme.onSurface),
        bodySmall: TextStyle(fontSize: 12, color: colorScheme.onSurface),
        labelLarge: TextStyle(fontSize: 14, color: colorScheme.onSurface),
        labelMedium: TextStyle(fontSize: 12, color: colorScheme.onSurface),
        labelSmall: TextStyle(fontSize: 11, color: colorScheme.onSurface),
      ),
    );
  }
}

 

  • Подлючаем этот класс в MaterialApp 
  • Используем метод Theme.of(context) для правильного получения значений темы
  • Для изменения стиля на основе существующего используем метод copyWith()

Файл main.dart

import 'package:course_2025/app_theme.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      title: "Hello Flutter App",
      theme: AppTheme.lightTheme(), // 👉 Используем тему
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Hello Flutter App"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Image.asset(
                "assets/images/roll.png", 
                width: 250,
              ),
              // 👉 УБИРАЕМ CONST
              Text(
                "Вкусные Роллы",
                // 👉 Получаем стиль текста из темы AppTheme
                style: Theme.of(context).textTheme.headlineMedium
              ),
              ElevatedButton(
                onPressed: () {
                  print("Вы купили роллы! Спасибо за заказ!");
                },
                // 👉 УБИРАЕМ CONST
                child: Text(
                  "Купить",
                  // 👉 Переопределяем стиль текста
                  style: Theme.of(context).textTheme.labelLarge?.copyWith(
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                    fontSize: 20,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}